/*
 *
 * Copyright 2018-2024 NXP.
 *
 * NXP Confidential. This software is owned or controlled by NXP and may only be
 * used strictly in accordance with the applicable license terms. By expressly
 * accepting such terms or by downloading,installing, activating and/or otherwise
 * using the software, you are agreeing that you have read,and that you agree to
 * comply with and are bound by, such license terms. If you do not agree to be
 * bound by the applicable license terms, then you may not retain, install, activate
 * or otherwise use the software.
 *
 */

#include "UwbApi_Proprietary_Internal.h"
#include "UwbApi_Internal.h"
#include "phNxpLogApis_UwbApi.h"
#include "uwa_api.h"
#include "phOsalUwb.h"
#include "uci_ext_defs.h"
#include "UwbAdaptation.h"
#include "AppConfigParams.h"
#include "PrintUtility.h"
#include "phNxpUwbConfig.h"
#include "uwa_dm_int.h"
#include "uwb_int.h"
#include "UwbApi_Utility.h"
#include "uwbiot_ver.h"
#include "UwbApi_Types.h"
#include "UwbApi.h"
#include "uwb_types.h"

/** Extended config header length (1 byte param id + 1 byte param len) */
#define UWBD_EXT_CONFIG_HEADER_LEN 0x02

/** Local functions prototypes */
static void handle_calib_status_ntf(uint8_t *p, uint16_t len);
static void handle_test_loopback_status_ntf(uint8_t *p, uint16_t len);
static void handle_msg_log_ntf(uint8_t *p, uint16_t len);
static void handle_ext_psdu_log_ntf(uint8_t *p, uint16_t len);

/**
 **
 ** Function:        getExtTLVBuffer
 **
 ** Description:     Convert one TLV Application Configuration Structure to Byte
 *Array
 **
 ** Returns:         Length of the data
 **
 */
uint8_t getExtTLVBuffer(uint8_t paramId, void *paramValue, uint8_t *tlvBuffer)
{
    uint8_t length      = 0;
    tlvBuffer[length++] = paramId;

    switch (paramId) {
    /* Length 2 Byte */
    case UCI_EXT_PARAM_ID_DPD_ENTRY_TIMEOUT:
    case UCI_EXT_PARAM_ID_HPD_ENTRY_TIMEOUT:
    case UCI_EXT_PARAM_ID_RX_TIMEOUT_ID:
    case SR040_INTERNAL_0xFD:
    case UCI_EXT_PARAM_ID_RX_RADIO_CFG_IDXS:
    case UCI_EXT_PARAM_ID_TX_RADIO_CFG_IDXS: {
        tlvBuffer[length++] = 2; // Param len
        uint16_t value      = *((uint16_t *)paramValue);
        tlvBuffer[length++] = (uint8_t)(value);
        tlvBuffer[length++] = (uint8_t)(value >> 8);
    } break;
    /* Length 1 Byte */
    case UCI_EXT_PARAM_ID_RANGING_START_OFFSET:
    case UCI_EXT_PARAM_ID_ULTDOA_MAC_FRAME_FORMAT:
    case UCI_EXT_PARAM_ID_RX_START_MARGIN_ID:
    case UCI_EXT_PARAM_ID_STS_INDEX_RESTART:
    case UCI_EXT_PARAM_ID_TX_POWER_ID:
    case UCI_EXT_PARAM_ID_DEBUG_LOG_LEVEL:
    case UCI_EXT_PARAM_ID_RX_PHY_LOGGING_ENBL:
    case UCI_EXT_PARAM_ID_TX_PHY_LOGGING_ENBL:
    case UCI_EXT_PARAM_ID_NBIC_CONF_ID:
    case UCI_EXT_PARAM_ID_ADAPTIVE_HOPPING_THRESHOLD:
    case UCI_EXT_PARAM_ID_MAC_CFG:
    case UCI_EXT_PARAM_ID_ANTENNA_CONFIG: {
        tlvBuffer[length++] = 1; // Param len
        tlvBuffer[length++] = *((uint8_t *)paramValue);
    } break;
    /* Length 4 Byte */
    case UCI_EXT_PARAM_ID_LOG_PARAMS_CONF: {
        tlvBuffer[length++] = 4; // Param len
        uint32_t value      = *((uint32_t *)paramValue);
        tlvBuffer[length++] = (uint8_t)(value);
        tlvBuffer[length++] = (uint8_t)(value >> 8);
        tlvBuffer[length++] = (uint8_t)(value >> 16);
        tlvBuffer[length++] = (uint8_t)(value >> 24);
    } break;
    case UCI_EXT_PARAM_ID_SALTED_HASH:
    case UCI_EXT_PARAM_ID_D_URSK: {
        uint8_t *value      = (uint8_t *)paramValue;
        tlvBuffer[length++] = 17; // Param len
        for (uint8_t i = 0; i < 17; i++) {
            tlvBuffer[length++] = *value++;
        }
    } break;
    default: {
        NXPLOG_UWBAPI_D("%s: Unknown ID\n", __FUNCTION__);
    } break;
    }
    return length;
}

BOOLEAN parseDeviceInfo(phUwbDevInfo_t *pdevInfo)
{
    uint8_t length              = 0;
    uint16_t index              = 0;
    uint16_t manufacturerLength = uwbContext.rsp_len;
    uint8_t *manufacturerData   = uwbContext.rsp_data;
    uint8_t device_info_len     = 0;

    if (manufacturerLength == 0) {
        NXPLOG_UWBAPI_E("%s: manufacturerLength is Zero", __FUNCTION__);
        return FALSE;
    }

    UWB_BE_STREAM_TO_UINT16(pdevInfo->uciGenericVersion, manufacturerData);
    UWB_STREAM_TO_UINT8(pdevInfo->macMajorVersion, manufacturerData);
    UWB_STREAM_TO_UINT8(pdevInfo->macMinorMaintenanceVersion, manufacturerData);
    UWB_STREAM_TO_UINT8(pdevInfo->phyMajorVersion, manufacturerData);
    UWB_STREAM_TO_UINT8(pdevInfo->phyMinorMaintenanceVersion, manufacturerData);
    UWB_BE_STREAM_TO_UINT16(pdevInfo->uciTestVersion, manufacturerData);
    UWB_STREAM_TO_UINT8(device_info_len, manufacturerData);

    pdevInfo->mwMajor = UWBIOTVER_STR_VER_MAJOR;
    pdevInfo->mwMinor = UWBIOTVER_STR_VER_MINOR;

    while (index < device_info_len) {
        uint8_t param_id = manufacturerData[index++];
        length           = manufacturerData[index++];
        switch (param_id) {
        case UCI_EXT_PARAM_ID_DEVICE_NAME:
            phOsalUwb_MemCopy(pdevInfo->devName, &manufacturerData[index], length);
            index = index + length;
            break;
        case UCI_EXT_PARAM_ID_FIRMWARE_VERSION:
            pdevInfo->fwMajor        = manufacturerData[index++];
            pdevInfo->fwMinor        = manufacturerData[index++];
            pdevInfo->fwPatchVersion = manufacturerData[index++];
            break;
        case UCI_EXT_PARAM_ID_DEVICE_VERSION:
            pdevInfo->devMajor = manufacturerData[index++];
            pdevInfo->devMinor = manufacturerData[index++];
            break;
        case UCI_EXT_PARAM_ID_SERIAL_NUMBER:
            phOsalUwb_MemCopy(pdevInfo->serialNo, &manufacturerData[index], length);
            index = index + length;
            break;
        case UCI_EXT_PARAM_ID_DSP_VERSION:
            pdevInfo->dspMajor        = manufacturerData[index++];
            pdevInfo->dspMinor        = manufacturerData[index++];
            pdevInfo->dspPatchVersion = manufacturerData[index++];
            break;
        case UCI_EXT_PARAM_ID_RANGER4_VERSION:
            pdevInfo->bbMajor = manufacturerData[index++];
            pdevInfo->bbMinor = manufacturerData[index++];
            break;
        case UCI_EXT_PARAM_ID_CCC_VERSION:
            phOsalUwb_MemCopy(pdevInfo->cccVersion, &manufacturerData[index], length);
            index = index + length;
            break;
        default:
            index = index + length;
            break;
        }
    }
    return TRUE;
}

/**
 **
 ** Function         handle_calib_status_ntf
 **
 ** Description      This function is called to notify calibration status
 **
 ** Returns          void
 **
 */
static void handle_calib_status_ntf(uint8_t *p, uint16_t len)
{
    phOsalUwb_SetMemory(&uwbContext.calibrationStatus, 0x00, sizeof(phCalibrationStatus_t));
    uwbContext.calibrationStatus.status = FAILURE;
    uint8_t status                      = 0xFF;
    if (len != 0) {
        UWB_STREAM_TO_UINT8(status, p);
        uwbContext.calibrationStatus.status = (eCalibStatus)status;
    }
}

/**
 **
 ** Function         handle_test_loopback_status_ntf
 **
 ** Description      This function is called to notify calibration status
 **
 ** Returns          void
 **
 */
static void handle_test_loopback_status_ntf(uint8_t *p, uint16_t len)
{
    if (uwbContext.pAppCallback) {
        uwbContext.pAppCallback(UWBD_TEST_MODE_LOOP_BACK_NTF, p, len);
    }
}

/**
 **
 ** Function         handle_msg_log_ntf
 **
 ** Description      This function is called to notify msg log
 **
 ** Returns          void
 **
 */
static void handle_msg_log_ntf(uint8_t *p, uint16_t len)
{
    if (uwbContext.pAppCallback) {
        uwbContext.pAppCallback(UWB_TEST_PHY_LOG_NTF, p, len);
    }
}

/**
 **
 ** Function         handle_ext_psdu_log_ntf
 **
 ** Description      This function is called to notify ext psdu msg log
 **
 ** Returns          void
 **
 */
static void handle_ext_psdu_log_ntf(uint8_t *p, uint16_t len)
{
    if (len == 0) {
        NXPLOG_UWBAPI_E("%s: PSDU Lenth is NULL", __FUNCTION__);
    }

    // if (uwbContext.pAppCallback) {
    //     uwbContext.pAppCallback(UWB_TEST_EXT_PSDU_LOG_NTF, p, len);
    // }
}

void extDeviceManagementCallback(uint8_t gid, uint8_t event, uint16_t paramLength, uint8_t *pResponseBuffer)
{
    uint16_t responsePayloadLen = 0;
    uint8_t *responsePayloadPtr = NULL;
    PHUWB_UNUSED(gid); // To make it compatible with SR1xx

    if ((paramLength >= UCI_RESPONSE_STATUS_OFFSET) && (pResponseBuffer != NULL)) {
        NXPLOG_UWBAPI_D("extDeviceManagementCallback: Received length data = 0x%x ", paramLength);

        responsePayloadLen         = (uint16_t)(paramLength - UCI_RESPONSE_STATUS_OFFSET);
        uwbContext.receivedEventId = (uint16_t)event;
        switch (event) {
        case EXT_UCI_MSG_SET_TRIM_VALUES_CMD: {
            responsePayloadPtr = &pResponseBuffer[UCI_RESPONSE_STATUS_OFFSET];
            handle_calib_status_ntf(responsePayloadPtr, responsePayloadLen);
        } break;
        case EXT_UCI_MSG_TEST_LOOPBACK_NTF: {
            NXPLOG_UWBAPI_D("%s: Test loopback Notification Received", __FUNCTION__);
            responsePayloadPtr = &pResponseBuffer[UCI_RESPONSE_STATUS_OFFSET];
            handle_test_loopback_status_ntf(responsePayloadPtr, responsePayloadLen);
        } break;
        case EXT_UCI_MSG_LOG_NTF: {
            NXPLOG_UWBAPI_D("%s: Log Notification Received", __FUNCTION__);
            responsePayloadPtr = &pResponseBuffer[UCI_RESPONSE_STATUS_OFFSET];
            handle_msg_log_ntf(responsePayloadPtr, responsePayloadLen);
        } break;
        case EXT_UCI_MSG_TEST_STOP_CMD: {
            NXPLOG_UWBAPI_D("%s: Test Stop Notification Received", __FUNCTION__);
        } break;
        case EXT_PSDU_LOG_NTF: {
            NXPLOG_UWBAPI_D("%s: Extented PSDU Log Notification Received", __FUNCTION__);
            responsePayloadPtr = &pResponseBuffer[UCI_RESPONSE_STATUS_OFFSET];
            handle_ext_psdu_log_ntf(responsePayloadPtr, responsePayloadLen);
        } break;
        default:
            NXPLOG_UWBAPI_E("%s: unhandled event", __FUNCTION__);
            break;
        }
        if (uwbContext.currentEventId == event || event == UWA_DM_UWBD_RESP_TIMEOUT_EVT) {
            NXPLOG_UWBAPI_D("%s: posting devMgmtSem\n", __FUNCTION__);
            uwbContext.currentEventId = DEFAULT_EVENT_TYPE;
            (void)phOsalUwb_ProduceSemaphore(uwbContext.devMgmtSem);
        }
    }
    else {
        NXPLOG_UWBAPI_E(
            "%s: pResponseBuffer is NULL or paramLength is less than "
            "UCI_RESPONSE_STATUS_OFFSET\n",
            __FUNCTION__);
    }
}

void formCalibrationCommand(uint8_t paramId, void *pCalibData, uint8_t *pSetCalibrationCmd, uint16_t *pCommandLength)
{
    phTxPowerDiffCalibData_t *pTxCalibData         = NULL;
    phFreqDiffCalibData_t *pFreqDiffData           = NULL;
    phAntennaDelayCalibData_t *pAntennaDelay       = NULL;
    uint8_t *pCurrLimitValue                       = NULL;
    phTxAdaptivePowerCalibData_t *pTxAdaptivePower = NULL;
    phDdfsToneConfigData_t *pDdfsToneConfigData    = NULL;
    uint8_t *pTempCompensFlag                      = NULL;
    phLut_xtal *pLutxtal                           = NULL;
    phLut_temp_t *pLutTemp                         = NULL;
    uint8_t *pTemperatureSource                    = NULL;
    uint32_t *pThermistorRp                        = NULL;
    uint32_t *pdpdTimerPenalty                     = NULL;
    int8_t *pTrimPowerControlPreamble10            = NULL;
    int8_t *pTrimPowerControlPreamble27            = NULL;
    uint8_t *pWakupSensorEnable                    = NULL;
    uint16_t *pSlowBlinkInterval                   = NULL;
    uint32_t *ptrimLock                            = NULL;
    uint8_t *pCustomLutEnbl                        = NULL;
    uint16_t *pLutTempRtOffset                     = NULL;
    uint16_t *pLutTempRtSlope                      = NULL;
    uint8_t *pPreambleCoeffOverride                = NULL;
    uint16_t *pMouleMakerId                        = NULL;
    uint16_t payloadLen                            = 3; // no of params + param ID + Length
    switch (paramId) {
    case TX_POWER_DIFF:
    case TX_POWER_DIFF_ANT_BOTTOM:
        pTxCalibData = (phTxPowerDiffCalibData_t *)pCalibData;
        payloadLen += TX_POWER_DIFF_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (eCalibParam)paramId);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TX_POWER_DIFF_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pTxCalibData->channelNo);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pTxCalibData->signVal);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pTxCalibData->absoluteVal);
        break;
    case FREQ_DIFF:
        pFreqDiffData = (phFreqDiffCalibData_t *)pCalibData;
        payloadLen += FREQUENCY_DIFF_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, FREQ_DIFF);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, FREQUENCY_DIFF_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pFreqDiffData->channelNo);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pFreqDiffData->signVal);
        UWB_UINT32_TO_STREAM(pSetCalibrationCmd, pFreqDiffData->absoluteFreqOffset);
        break;
    case ANTENNA_DELAY:
    case ANTENNA_DELAY_ANT_BOTTOM:
        pAntennaDelay = (phAntennaDelayCalibData_t *)pCalibData;
        payloadLen += ANTENNA_DELAY_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (eCalibParam)paramId);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, ANTENNA_DELAY_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pAntennaDelay->channelNo);
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pAntennaDelay->antennaDelay);
        break;
    case CURRENT_LIMIT_VALUE:
        pCurrLimitValue = (uint8_t *)pCalibData;
        payloadLen += CURRENT_LIMIT_VALUE_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, CURRENT_LIMIT_VALUE);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, CURRENT_LIMIT_VALUE_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (*pCurrLimitValue));
        break;
    case TX_ADAPTIVE_POWER_CALC:
    case TX_ADAPTIVE_POWER_CALC_ANT_BOTTOM:
        pTxAdaptivePower = (phTxAdaptivePowerCalibData_t *)pCalibData;
        payloadLen += TX_ADAPTIVE_POWER_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (eCalibParam)paramId);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TX_ADAPTIVE_POWER_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pTxAdaptivePower->channelNo);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pTxAdaptivePower->powerIdRms);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pTxAdaptivePower->peakDelta);
        break;
    case DDFS_TONE_VALUES:
        pDdfsToneConfigData = (phDdfsToneConfigData_t *)pCalibData;
        payloadLen += DDFS_TONE_CONFIG_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, DDFS_TONE_VALUES);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, DDFS_TONE_CONFIG_LEN);
        for (uint32_t LoopCnt = 0; LoopCnt < 4; ++LoopCnt) {
            UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].channelNo);
            UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].rfu);
            UWB_UINT32_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].txDdfsTone0RegVal);
            UWB_UINT32_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].txDdfsTone1RegVal);
            UWB_UINT32_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].spurDuration);
            UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].gainvalsetRegVal);
            UWB_UINT8_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].gainByPassEnblRegVal);
            UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pDdfsToneConfigData[LoopCnt].spurPeriodicity);
        }
        break;
    case TEMP_COMPENS_FLAG:
        pTempCompensFlag = (uint8_t *)pCalibData;
        payloadLen += TEMP_COMPENS_FLAG_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TEMP_COMPENS_FLAG);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TEMP_COMPENS_FLAG_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (*pTempCompensFlag));
        break;
    case TEMPERATURE_SOURCE:
        pTemperatureSource = (uint8_t *)pCalibData;
        payloadLen += TEMPERATURE_SOURCE_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TEMPERATURE_SOURCE);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TEMPERATURE_SOURCE_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (*pTemperatureSource));
        break;
    case THERMISTOR_RP:
        pThermistorRp = (uint32_t *)pCalibData;
        payloadLen += THERMISTOR_RP_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, THERMISTOR_RP);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, THERMISTOR_RP_LEN);
        UWB_UINT32_TO_STREAM(pSetCalibrationCmd, (*pThermistorRp));
        break;
    case DPD_TIMER_PENALTY_US:
        pdpdTimerPenalty = (uint32_t *)pCalibData;
        payloadLen += DPD_TIMER_PENALTY_US_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, DPD_TIMER_PENALTY_US);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, DPD_TIMER_PENALTY_US_LEN);
        UWB_UINT32_TO_STREAM(pSetCalibrationCmd, (*pdpdTimerPenalty));
        break;
    case TRIM_POWER_CTRL_PREAMBLE_10:
        pTrimPowerControlPreamble10 = (int8_t *)pCalibData;
        payloadLen += TRIM_BACKOFF_PREAMBLE_10_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_POWER_CTRL_PREAMBLE_10);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_BACKOFF_PREAMBLE_10_LEN);
        UWB_INT8_TO_STREAM(pSetCalibrationCmd, (*pTrimPowerControlPreamble10));
        break;
    case TRIM_POWER_CTRL_PREAMBLE_27:
        pTrimPowerControlPreamble27 = (int8_t *)pCalibData;
        payloadLen += TRIM_BACKOFF_PREAMBLE_27_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_POWER_CTRL_PREAMBLE_27);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_BACKOFF_PREAMBLE_27_LEN);
        UWB_INT8_TO_STREAM(pSetCalibrationCmd, (*pTrimPowerControlPreamble27));
        break;
    case LUT_XTAL:
        pLutxtal = (phLut_xtal *)pCalibData;
        payloadLen += LUT_XTAL_LEN + (pLutxtal->xtalLength);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, LUT_XTAL);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, payloadLen - 3); // extract the header
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pLutxtal->xtalStartAddress);
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pLutxtal->xtalLength);
        for (uint8_t LoopCnt = 0; LoopCnt < (pLutxtal->xtalLength) / 2; ++LoopCnt) {
            UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pLutxtal->xtalValue[LoopCnt]);
        }
        break;
    case LUT_THERMISTER:
        pLutTemp = (phLut_temp_t *)pCalibData;
        payloadLen += LUT_TEMP_LEN + (pLutTemp->tempLength);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, LUT_THERMISTER);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, payloadLen - 3); // extract the header
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pLutTemp->tempStartAddress);
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pLutTemp->tempLength);
        for (uint8_t LoopCnt = 0; LoopCnt < (pLutTemp->tempLength) / 2; ++LoopCnt) {
            UWB_UINT16_TO_STREAM(pSetCalibrationCmd, pLutTemp->tempValue[LoopCnt]);
        }
        break;
    case WAKEUP_SENSOR_ENABLE:
        pWakupSensorEnable = (uint8_t *)pCalibData;
        payloadLen += WAKEUP_SENSOR_ENABLE_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, WAKEUP_SENSOR_ENABLE);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, WAKEUP_SENSOR_ENABLE_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (*pWakupSensorEnable));
        break;
    case SLOW_BLINK_INTERVAL:
        pSlowBlinkInterval = (uint16_t *)pCalibData;
        payloadLen += SLOW_BLINK_INTERVAL_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, SLOW_BLINK_INTERVAL);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, SLOW_BLINK_INTERVAL_LEN);
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, (*pSlowBlinkInterval));
        break;
    case TRIM_LOCK:
        ptrimLock = (uint32_t *)pCalibData;
        payloadLen += TRIM_LOCK_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_LOCK);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_LOCK_LEN);
        UWB_UINT32_TO_STREAM(pSetCalibrationCmd, (*ptrimLock));
        break;
    case CUSTOM_LUTS_ENBL:
        pCustomLutEnbl = (uint8_t *)pCalibData;
        payloadLen += CUSTOM_LUT_ENBL_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, CUSTOM_LUTS_ENBL);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, CUSTOM_LUT_ENBL_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (*pCustomLutEnbl));
        break;
    case LUT_TEMP_RT_OFFSET:
        pLutTempRtOffset = (uint16_t *)pCalibData;
        payloadLen += LUT_TEMP_RT_OFFSET_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, LUT_TEMP_RT_OFFSET);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, LUT_TEMP_RT_OFFSET_LEN);
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, (*pLutTempRtOffset));
        break;
    case LUT_TEMP_RT_SLOPE:
        pLutTempRtSlope = (uint16_t *)pCalibData;
        payloadLen += LUT_TEMP_RT_SLOPE_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, LUT_TEMP_RT_SLOPE);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, LUT_TEMP_RT_SLOPE_LEN);
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, (*pLutTempRtSlope));
        break;
    case TRIM_PREAMBLE_10_27_PAYLOAD_PS_COEFFS_OVERRIDE:
        pPreambleCoeffOverride = (uint8_t *)pCalibData;
        payloadLen += TRIM_PREAMBLE_10_27_PAYLOAD_PS_COEFFS_OVERRIDE_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_PREAMBLE_10_27_PAYLOAD_PS_COEFFS_OVERRIDE);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, TRIM_PREAMBLE_10_27_PAYLOAD_PS_COEFFS_OVERRIDE_LEN);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, (*pPreambleCoeffOverride));
        break;
    case MODULE_MAKER_ID:
        pMouleMakerId = (uint16_t *)pCalibData;
        payloadLen += MODULE_MAKER_ID_LEN;
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, 1);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, MODULE_MAKER_ID);
        UWB_UINT8_TO_STREAM(pSetCalibrationCmd, MODULE_MAKER_ID_LEN);
        UWB_UINT16_TO_STREAM(pSetCalibrationCmd, (*pMouleMakerId));
        break;
    default:
        break;
    }
    *pCommandLength = payloadLen;
}

bool formTestModeCommand(
    eTestMode testMode, const phTestModeParams *testModeParams, uint8_t *pCommand, uint16_t *pCommandLength)
{
    uint8_t payloadLen             = 0;
    uint8_t transmitModeNoOfParams = 0;
    uint16_t psduFrameLen          = 0;
    switch (testMode) {
    case RECEIVE_MODE:
        // PayloadLength = size of Number of Params(1 Byte) + No of Params * 2 Byte (1 Byte Type, 1 Byte Length) +
        // Length of all N parameters
        payloadLen = (uint8_t)(1 + (UCI_EXT_RECEIVE_MODE_NO_OF_PARAMS * 2) + UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN +
                               UCI_EXT_TEST_MODE_ID_DELAY_LEN + UCI_EXT_TEST_MODE_ID_SLOT_TYPE_LEN +
                               UCI_EXT_TEST_MODE_ID_EVENT_COUNTER_MAX_LEN + UCI_EXT_TEST_MODE_ID_CYCLE_TIME_LEN +
                               UCI_EXT_TEST_MODE_ID_TIME_OUT_LEN + UCI_EXT_TEST_MODE_ID_PHR_RANGING_BIT_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_RECEIVE_MODE_NO_OF_PARAMS);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_RECEIVE_MODE);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_SLOT_TYPE);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_SLOT_TYPE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, testModeParams->receiveModeParams.commonParams.slotType);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_DELAY);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_DELAY_LEN);
        UWB_UINT16_TO_STREAM(pCommand, testModeParams->receiveModeParams.commonParams.startDelay);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_EVENT_COUNTER_MAX);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_EVENT_COUNTER_MAX_LEN);
        UWB_UINT32_TO_STREAM(pCommand, testModeParams->receiveModeParams.commonParams.eventCounterMax);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_CYCLE_TIME);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_CYCLE_TIME_LEN);
        UWB_UINT32_TO_STREAM(pCommand, testModeParams->receiveModeParams.cycleTime);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TIME_OUT);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TIME_OUT_LEN);
        UWB_UINT16_TO_STREAM(pCommand, testModeParams->receiveModeParams.timeOut);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_PHR_RANGING_BIT);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_PHR_RANGING_BIT_LEN);
        UWB_UINT16_TO_STREAM(
            pCommand, testModeParams->receiveModeParams.commonParams.slotType == kUWB_SR040_TxRxSlotType_SP0 ? 0 : 1);
        break;
    case TRANSMIT_MODE:
        /*following flow will handle the PSDU data frame more than 127 (HPRF) and else part will handle the BPRF part*/
        if (testModeParams->transmitModeParams.psduLen > BPRF_MAX_PSDU_FRAME_SIZE) {
            transmitModeNoOfParams = UCI_EXT_TRANSMIT_MODE_NO_OF_PARAMS - 1; // removing psdu parameter
            // PayloadLength = size of Number of Params(1 Byte) + No of Params * 2 Byte (1 Byte Type, 1 Byte Length) +
            // Length of all N parameters
            payloadLen = (uint8_t)(1 + (transmitModeNoOfParams * 2) + UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN +
                                   UCI_EXT_TEST_MODE_ID_DELAY_LEN + UCI_EXT_TEST_MODE_ID_SLOT_TYPE_LEN +
                                   UCI_EXT_TEST_MODE_ID_EVENT_COUNTER_MAX_LEN + UCI_EXT_TEST_MODE_ID_CYCLE_TIME_LEN +
                                   UCI_EXT_TEST_MODE_ID_PHR_RANGING_BIT_LEN);

            // adding frame count as well in No parameter
            psduFrameLen = testModeParams->transmitModeParams.psduLen; // adding frame count as well in No parameter
            while (psduFrameLen) {
                if (psduFrameLen > EXTENDED_PSDU_FRAME_MAX_SIZE_HPRF) {
                    psduFrameLen = psduFrameLen - EXTENDED_PSDU_FRAME_MAX_SIZE_HPRF;
                    transmitModeNoOfParams++;
                }
                else {
                    transmitModeNoOfParams++;
                    psduFrameLen = 0;
                }
            }

            UWB_UINT8_TO_STREAM(pCommand, transmitModeNoOfParams);
        }
        else {
            // PayloadLength = size of Number of Params(1 Byte) + No of Params * 2 Byte (1 Byte Type, 1 Byte Length) +
            // Length of all N parameters
            payloadLen =
                (uint8_t)(1 + (UCI_EXT_TRANSMIT_MODE_NO_OF_PARAMS * 2) + UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN +
                          UCI_EXT_TEST_MODE_ID_DELAY_LEN + UCI_EXT_TEST_MODE_ID_SLOT_TYPE_LEN +
                          UCI_EXT_TEST_MODE_ID_EVENT_COUNTER_MAX_LEN + UCI_EXT_TEST_MODE_ID_CYCLE_TIME_LEN +
                          testModeParams->transmitModeParams.psduLen + UCI_EXT_TEST_MODE_ID_PHR_RANGING_BIT_LEN);

            UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TRANSMIT_MODE_NO_OF_PARAMS);
        }

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_TRANSMIT_MODE);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_SLOT_TYPE);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_SLOT_TYPE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, testModeParams->transmitModeParams.commonParams.slotType);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_DELAY);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_DELAY_LEN);
        UWB_UINT16_TO_STREAM(pCommand, testModeParams->transmitModeParams.commonParams.startDelay);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_EVENT_COUNTER_MAX);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_EVENT_COUNTER_MAX_LEN);
        UWB_UINT32_TO_STREAM(pCommand, testModeParams->transmitModeParams.commonParams.eventCounterMax);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_CYCLE_TIME);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_CYCLE_TIME_LEN);
        UWB_UINT32_TO_STREAM(pCommand, testModeParams->transmitModeParams.cycleTime);

        if (testModeParams->transmitModeParams.psduLen <= BPRF_MAX_PSDU_FRAME_SIZE) {
            UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_PSDU);
            UWB_UINT8_TO_STREAM(pCommand, testModeParams->transmitModeParams.psduLen);
            UWB_ARRAY_TO_STREAM(
                pCommand, testModeParams->transmitModeParams.psduData, testModeParams->transmitModeParams.psduLen);
        }

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_PHR_RANGING_BIT);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_PHR_RANGING_BIT_LEN);
        UWB_UINT16_TO_STREAM(
            pCommand, testModeParams->transmitModeParams.commonParams.slotType == kUWB_SR040_TxRxSlotType_SP0 ? 0 : 1);
        break;
    case CONTINUOUS_WAVE_MODE:
        // PayloadLength = size of Number of Params(1 Byte) + No of Params * 2 Byte (1 Byte Type, 1 Byte Length) +
        // Length of all N parameters
        payloadLen =
            (uint8_t)(1 + (UCI_EXT_CONTINUOUS_WAVE_MODE_NO_OF_PARAMS * 2) + UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_CONTINUOUS_WAVE_MODE_NO_OF_PARAMS);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_CONTINUOUS_WAVE_MODE);
        break;
    case LOOP_BACK_MODE:
        // PayloadLength = size of Number of Params(1 Byte) + No of Params * 2 Byte (1 Byte Type, 1 Byte Length) +
        // Length of all N parameters
        payloadLen = (uint8_t)(1 + (UCI_EXT_LOOP_BACK_MODE_NO_OF_PARAMS * 2) + UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_LOOP_BACK_MODE_NO_OF_PARAMS);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_LOOP_BACK_MODE);
        break;
    case LOOP_BACK_MODE_NVM_AND_SAVE:
        // PayloadLength = size of Number of Params(1 Byte) + No of Params * 2 Byte (1 Byte Type, 1 Byte Length) +
        // Length of all N parameters
        payloadLen = (uint8_t)(1 + (UCI_EXT_LOOP_BACK_MODE_NO_OF_PARAMS * 2) + UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_LOOP_BACK_MODE_NO_OF_PARAMS);

        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_ID_TEST_MODE_LEN);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_TEST_MODE_LOOP_BACK_AND_SAVE_MODE);
        break;
    case SS_TWR_MODE:
        payloadLen = (uint8_t)(1 + UCI_EXT_SSTWR_MODE_NO_OF_PARAMS);
        UWB_UINT8_TO_STREAM(pCommand, payloadLen);
        UWB_UINT8_TO_STREAM(pCommand, UCI_EXT_SSTWR_MODE_NO_OF_PARAMS);
        break;
    default:
        NXPLOG_UWBAPI_E("%s: Invalid Test Mode", __FUNCTION__);
        return FALSE;
    }
    *pCommandLength = payloadLen;
    return TRUE;
}

tUWBAPI_STATUS setDefaultCoreConfigs(void)
{
    /* By default PASS, if nothing to set */
    tUWBAPI_STATUS status = UWBAPI_STATUS_OK;
    uint8_t config        = 0;
    uint16_t dpdTimeout   = 0;
    uint16_t hpdTimeout   = 0;
    uint8_t offset        = 1;

    NXPLOG_UWBAPI_D("%s: Enter ", __FUNCTION__);

    if (phNxpUciHal_GetNxpNumValue(UWB_DPD_ENTRY_TIMEOUT, &dpdTimeout, 0x02) == TRUE) {
        NXPLOG_UWBAPI_D("%s: UWB_DPD_ENTRY_TIMEOUT value %d ", __FUNCTION__, dpdTimeout);

        offset = 1;
        offset = (uint8_t)getExtTLVBuffer(
            UCI_EXT_PARAM_ID_DPD_ENTRY_TIMEOUT, (void *)&dpdTimeout, &uwbContext.snd_data[offset]);

        uwbContext.snd_data[0] = 1; // No of parameters
        sep_SetWaitEvent(UWA_DM_CORE_SET_CONFIG_RSP_EVT);
        status = sendUciCommandAndWait(UWA_DM_API_CORE_SET_CONFIG_EVT, (uint16_t)(offset + 1), uwbContext.snd_data);
        if (status == UWBAPI_STATUS_OK) {
            NXPLOG_UWBAPI_D("%s: UCI_EXT_PARAM_ID_DPD_ENTRY_TIMEOUT config is Success", __FUNCTION__);
        }
        else if (status == UWBAPI_STATUS_TIMEOUT) {
            return status;
        }
        else {
            NXPLOG_UWBAPI_E("%s: UCI_EXT_PARAM_ID_DPD_ENTRY_TIMEOUT config is failed", __FUNCTION__);
        }
    }
    else {
        NXPLOG_UWBAPI_D("%s: UCI_EXT_PARAM_ID_DPD_ENTRY_TIMEOUT config not found", __FUNCTION__);
    }

    if (phNxpUciHal_GetNxpNumValue(UWB_HPD_ENTRY_TIMEOUT, &hpdTimeout, 0x02) == TRUE) {
        NXPLOG_UWBAPI_D("%s: UWB_HPD_ENTRY_TIMEOUT value %d ", __FUNCTION__, hpdTimeout);

        offset = 1;
        offset = (uint8_t)getExtTLVBuffer(
            UCI_EXT_PARAM_ID_HPD_ENTRY_TIMEOUT, (void *)&hpdTimeout, &uwbContext.snd_data[offset]);

        uwbContext.snd_data[0] = 1; // No of parameters
        sep_SetWaitEvent(UWA_DM_CORE_SET_CONFIG_RSP_EVT);
        status = sendUciCommandAndWait(UWA_DM_API_CORE_SET_CONFIG_EVT, (uint16_t)(offset + 1), uwbContext.snd_data);
        if (status == UWBAPI_STATUS_OK) {
            NXPLOG_UWBAPI_D("%s: UCI_EXT_PARAM_ID_HPD_ENTRY_TIMEOUT config is Success", __FUNCTION__);
        }
        else if (status == UWBAPI_STATUS_TIMEOUT) {
            return status;
        }
        else {
            NXPLOG_UWBAPI_E("%s: UCI_EXT_PARAM_ID_HPD_ENTRY_TIMEOUT config is failed", __FUNCTION__);
        }
    }
    else {
        NXPLOG_UWBAPI_D("%s: Hpd Entry Timeout config not found", __FUNCTION__);
    }

    if (phNxpUciHal_GetNxpNumValue(UWB_LOW_POWER_MODE, &config, 0x01) == TRUE) {
        NXPLOG_UWBAPI_D("%s: UWB_LOW_POWER_MODE value %d ", __FUNCTION__, (uint8_t)config);

        offset = 1;

        offset = (uint8_t)getCoreDeviceConfigTLVBuffer(
            UCI_PARAM_ID_LOW_POWER_MODE, sizeof(config), (void *)&config, &uwbContext.snd_data[offset]);

        uwbContext.snd_data[0] = 1; // No of parameters
        sep_SetWaitEvent(UWA_DM_CORE_SET_CONFIG_RSP_EVT);
        status = sendUciCommandAndWait(UWA_DM_API_CORE_SET_CONFIG_EVT, (uint16_t)(offset + 1), uwbContext.snd_data);
        if (status == UWBAPI_STATUS_OK) {
            NXPLOG_UWBAPI_D("%s: low power mode config is Success", __FUNCTION__);
        }
        else if (status == UWBAPI_STATUS_TIMEOUT) {
            return status;
        }
        else {
            NXPLOG_UWBAPI_E("%s: low power mode config is failed", __FUNCTION__);
        }
    }
    else {
        NXPLOG_UWBAPI_D("%s: low power mode config not found", __FUNCTION__);
    }

    if (phNxpUciHal_GetNxpNumValue(UWB_MHR_IN_CCM, &config, 0x01) == TRUE) {
        NXPLOG_UWBAPI_D("%s: UWB_MHR_IN_CCM value %d ", __FUNCTION__, (uint8_t)config);
        offset = 1;
        offset = (uint8_t)getCoreDeviceConfigTLVBuffer(
            UCI_EXT_PARAM_ID_MHR_IN_CCM, sizeof(config), (void *)&config, &uwbContext.snd_data[offset]);
        uwbContext.snd_data[0] = 1;
        sep_SetWaitEvent(UWA_DM_CORE_SET_CONFIG_RSP_EVT);
        status = sendUciCommandAndWait(UWA_DM_API_CORE_SET_CONFIG_EVT, (uint16_t)(offset + 1), uwbContext.snd_data);
        if (status == UWBAPI_STATUS_OK) {
            NXPLOG_UWBAPI_D("%s: UCI_EXT_PARAM_ID_MHR_IN_CCM config is Success", __FUNCTION__);
        }
        else if (status == UWBAPI_STATUS_TIMEOUT) {
            return status;
        }
        else {
            NXPLOG_UWBAPI_E("%s: UCI_EXT_PARAM_ID_MHR_IN_CCM config is failed", __FUNCTION__);
        }
    }
    else {
        NXPLOG_UWBAPI_D("%s: MHR in CCM config not found", __FUNCTION__);
    }

    if (phNxpUciHal_GetNxpNumValue(UWB_DDFS_TONE_CONFIG_ENABLE, &config, 0x01) == TRUE) {
        NXPLOG_UWBAPI_D("%s: UWB_DDFS_TONE_CONFIG_ENABLE value %d ", __FUNCTION__, (uint8_t)config);
        offset = 1;
        offset = (uint8_t)getCoreDeviceConfigTLVBuffer(
            UCI_EXT_PARAM_ID_DDFS_TONE_CONFIG_ENABLE, sizeof(config), (void *)&config, &uwbContext.snd_data[offset]);
        uwbContext.snd_data[0] = 1;
        sep_SetWaitEvent(UWA_DM_CORE_SET_CONFIG_RSP_EVT);

        status = sendUciCommandAndWait(UWA_DM_API_CORE_SET_CONFIG_EVT, (uint16_t)(offset + 1), uwbContext.snd_data);
        if (status == UWBAPI_STATUS_OK) {
            NXPLOG_UWBAPI_D("%s: UCI_EXT_PARAM_ID_DDFS_TONE_CONFIG_ENABLE config is Success", __FUNCTION__);
        }
        else if (status == UWBAPI_STATUS_TIMEOUT) {
            return status;
        }
        else {
            NXPLOG_UWBAPI_E("%s: UCI_EXT_PARAM_ID_DDFS_TONE_CONFIG_ENABLE config is failed", __FUNCTION__);
        }
    }
    else {
        NXPLOG_UWBAPI_D("%s: DDFS TONE CONFIG ENABLE config not found", __FUNCTION__);
    }

    NXPLOG_UWBAPI_D("%s: Exit ", __FUNCTION__);
    return status;
}

uint8_t getExtCoreDeviceConfigTLVBuffer(uint8_t paramId, uint8_t paramLen, void *paramValue, uint8_t *tlvBuffer)
{
    uint8_t length = (uint8_t)(paramLen + UWBD_EXT_CONFIG_HEADER_LEN);

    if (paramValue == NULL || tlvBuffer == NULL) {
        NXPLOG_UWBAPI_E("%s: Buffer is NULL", __FUNCTION__);
        return 0;
    }
    UWB_UINT8_TO_STREAM(tlvBuffer, paramId);
    UWB_UINT8_TO_STREAM(tlvBuffer, paramLen);

    switch (paramId) {
        /* Length 1 byte */
    case UCI_EXT_PARAM_ID_DDFS_TONE_CONFIG_ENABLE: {
        uint8_t value = *((uint8_t *)paramValue);
        UWB_UINT8_TO_STREAM(tlvBuffer, value);
    } break;
    case UCI_EXT_PARAM_ID_MHR_IN_CCM: {
        uint8_t value = *((uint8_t *)paramValue);
        UWB_UINT8_TO_STREAM(tlvBuffer, value);
    } break;
    case UCI_EXT_PARAM_ID_NXP_EXTENDED_NTF_CONFIG: {
        uint8_t value = *((uint8_t *)paramValue);
        UWB_UINT8_TO_STREAM(tlvBuffer, value);
    } break;
        /* Length 2 byte */
    case UCI_EXT_PARAM_ID_HPD_ENTRY_TIMEOUT: {
        uint16_t value = *((uint16_t *)paramValue);
        UWB_UINT16_TO_STREAM(tlvBuffer, value);
    } break;
    case UCI_EXT_PARAM_ID_DPD_ENTRY_TIMEOUT: {
        uint16_t value = *((uint16_t *)paramValue);
        UWB_UINT16_TO_STREAM(tlvBuffer, value);
    } break;
        /* Length 4 byte */
    default:
        length = 0;
    }
    return length;
}

void parseExtGetDeviceConfigResponse(uint8_t *tlvBuffer, phDeviceConfigData_t *devConfig)
{
    uint8_t paramId;
    UWB_STREAM_TO_UINT8(paramId, tlvBuffer);
    tlvBuffer = tlvBuffer + 2; // skip the header
    switch (paramId) {
    /* 1 byte len */
    case UCI_EXT_PARAM_ID_MHR_IN_CCM: {
        UWB_STREAM_TO_UINT8(devConfig->mhrInCcm, tlvBuffer);
    } break;
    case UCI_EXT_PARAM_ID_DDFS_TONE_CONFIG_ENABLE: {
        UWB_STREAM_TO_UINT8(devConfig->ddfsToneConfig, tlvBuffer);
    } break;
    case UCI_EXT_PARAM_ID_NXP_EXTENDED_NTF_CONFIG: {
        UWB_STREAM_TO_UINT8(devConfig->nxpExtendedNtfConfig, tlvBuffer);
    } break;
    /* Length 2 byte */
    case UCI_EXT_PARAM_ID_DPD_ENTRY_TIMEOUT: {
        UWB_STREAM_TO_UINT16(devConfig->dpdEntryTimeout, tlvBuffer);
    } break;
    case UCI_EXT_PARAM_ID_HPD_ENTRY_TIMEOUT: {
        UWB_STREAM_TO_UINT16(devConfig->hpdEntryTimeout, tlvBuffer);
    } break;
    default:
        break;
    }
}

tUWBAPI_STATUS UpdateRadioSettings(uint8_t index, const uint8_t *pValue, uint16_t size, uint16_t crc)
{
    tUWBAPI_STATUS status;
    uint16_t respLen = 0x05;
    uint8_t respBuf[5];
    uint16_t radio_cfg_dnd_seq;

    uint8_t UCI_RadioCfg_Init_Seq[] = {(UCI_MT_CMD << UCI_MT_SHIFT) | UCI_GID_PROPRIETARY,
        EXT_UCI_MSG_RADIO_CONFIG_DOWNLOAD_CMD,
        0x00,
        0x02,
        kSR040_RadioCrc_InitDownload,
        0x00};

    uint8_t UCI_RadioCfg_DownLoad_Chunk[8 + 128] = {(UCI_MT_CMD << UCI_MT_SHIFT) | UCI_GID_PROPRIETARY,
        EXT_UCI_MSG_RADIO_CONFIG_DOWNLOAD_CMD,
        0x00,
        (1 + 2 + 1 + 0x80),
        kSR040_RadioCrc_DownloadChunk,
        0x00,
        0x00,
        0x80};

    uint8_t UCI_RadioCfg_Flash_Seq[] = {(UCI_MT_CMD << UCI_MT_SHIFT) | UCI_GID_PROPRIETARY,
        EXT_UCI_MSG_RADIO_CONFIG_DOWNLOAD_CMD,
        0x00,
        0x03,
        kSR040_RadioCrc_Finish,
        0x00,
        0x00};

    UCI_RadioCfg_Init_Seq[5] = index;

    UCI_RadioCfg_Flash_Seq[5] = crc & 0xFF;
    UCI_RadioCfg_Flash_Seq[6] = crc >> 8;

    status = UwbApi_SendRawCommand(UCI_RadioCfg_Init_Seq, sizeof(UCI_RadioCfg_Init_Seq), respBuf, &respLen);
    if (UWBAPI_STATUS_OK != status) {
        NXPLOG_UWBAPI_E("RadioSettings Failed while Transfer the Radio configuration Int Seq");
        goto exit;
    }

    for (radio_cfg_dnd_seq = 0; radio_cfg_dnd_seq < size; radio_cfg_dnd_seq += 128) {
        UCI_RadioCfg_DownLoad_Chunk[5] = radio_cfg_dnd_seq;
        UCI_RadioCfg_DownLoad_Chunk[6] = radio_cfg_dnd_seq >> 8;
        phOsalUwb_MemCopy(&UCI_RadioCfg_DownLoad_Chunk[8], pValue + radio_cfg_dnd_seq, 128);
        status =
            UwbApi_SendRawCommand(UCI_RadioCfg_DownLoad_Chunk, sizeof(UCI_RadioCfg_DownLoad_Chunk), respBuf, &respLen);
        if (UWBAPI_STATUS_OK != status) {
            NXPLOG_UWBAPI_E(
                "RadioSettings Failed while Downloading Radio configuration chunk at %d", radio_cfg_dnd_seq);
            goto exit;
        }
    }
    status = UwbApi_SendRawCommand(UCI_RadioCfg_Flash_Seq, sizeof(UCI_RadioCfg_Flash_Seq), respBuf, &respLen);
    if (UWBAPI_STATUS_OK != status) {
        NXPLOG_UWBAPI_E("RadioSettings Failed at Radio configuration Flash Sequence finish");
        goto exit;
    }

exit:
    NXPLOG_UWBAPI_D("%s: Exit", __FUNCTION__);
    return status;
}